home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 11 Learning / 04 Mommersteeg / Tennis / DirectDraw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-23  |  11.5 KB  |  472 lines

  1. //----------------------------------------------------------------------------------------------
  2. // Sequential Prediction Demo: The positioning pattern
  3. // 
  4. // Author:  Fri Mommersteeg
  5. // Date:    10-09-2001
  6. // File:    DirectDraw.cpp
  7. //----------------------------------------------------------------------------------------------
  8.  
  9. //----------------------------------------------------------------------------------------------
  10. // Include files
  11. //----------------------------------------------------------------------------------------------
  12.  
  13. #include "stdafx.h"
  14. #include "DirectDraw.h"
  15. #include <stdio.h>
  16.  
  17. //----------------------------------------------------------------------------------------------
  18. // The following functions are from some old, long forgotten personal DX library. I couldn't 
  19. // find the courage to document them properly, but take a look if you like...
  20. //----------------------------------------------------------------------------------------------
  21.  
  22.  
  23. extern BOOL RestoreAll(BOOL reinit);
  24.  
  25. LPDD            lpdd    = NULL;
  26. LPDDS            lpddps    = NULL;
  27. LPDDS            lpddss    = NULL;
  28.  
  29. HRESULT WINAPI EnumSurfacesCallback2(LPDIRECTDRAWSURFACE7 lpDDSurface,  LPDDSURFACEDESC2 lpDDSurfaceDesc,  LPVOID lpContext){
  30.     if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER){
  31.         lpddss =  lpDDSurface;
  32.         return DDENUMRET_CANCEL;
  33.     }
  34.     return DDENUMRET_OK;
  35. }
  36.  
  37. BOOL InitDD(HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWORD dwBitsPerPixel, DWORD dwBackBufferCount) {
  38.     LPDIRECTDRAW gpDD;
  39.     HRESULT    ddrval;
  40.     DDSD ddsd;
  41.  
  42.     ddrval = DirectDrawCreate(NULL, &gpDD, NULL);
  43.     if (ddrval != DD_OK)
  44.         return FALSE;
  45.  
  46.     ddrval = gpDD->QueryInterface(IID_IDirectDraw7, (LPVOID *) & lpdd);
  47.     if (ddrval != DD_OK)
  48.         return FALSE;
  49.  
  50.     gpDD->Release();
  51.  
  52.     ddrval = lpdd->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  53.     if (ddrval != DD_OK) {
  54.         MessageBox(NULL, "Could not set cooperative level!", "", 0);
  55.         return FALSE;
  56.     }
  57.  
  58.     ddrval = lpdd->SetDisplayMode(dwWidth, dwHeight, dwBitsPerPixel, 0, 0);
  59.     if (ddrval != DD_OK) {
  60.         MessageBox(NULL, "Could not set display mode!", "", 0);
  61.         return FALSE;
  62.     }
  63.  
  64.     ZeroMemory(&ddsd, sizeof(ddsd));
  65.     ddsd.dwSize = sizeof(ddsd);
  66.     
  67.     if (dwBackBufferCount>0) {
  68.         ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  69.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  70.         ddsd.dwBackBufferCount = dwBackBufferCount;
  71.     }
  72.     else {
  73.         ddsd.dwFlags = DDSD_CAPS;
  74.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  75.     }
  76.     
  77.     ddrval = lpdd->CreateSurface(&ddsd, &lpddps, NULL);
  78.     if (ddrval != DD_OK) {
  79.         MessageBox(NULL, "Could not get primary surface!", "", 0);
  80.         return FALSE;
  81.     }
  82.  
  83.     if (dwBackBufferCount>0) {
  84.         lpddps->EnumAttachedSurfaces(0,&EnumSurfacesCallback2);
  85.     } else {
  86.         lpddss = NULL;
  87.     }        
  88. #if 0 // there appears to be a bug with GetAttachedSurfaces on some versions of DirectX...
  89.     DDSCAPS2 ddscaps;
  90.     if (dwBackBufferCount>0) {
  91.         ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  92.         ddrval = lpddps->GetAttachedSurface(&ddscaps, &lpddss);
  93.         if (ddrval != DD_OK) {
  94.             MessageBox(NULL, "Could not get secondary surface!", "", 0);
  95.             return FALSE;
  96.         }
  97.     } else {
  98.         lpddss = NULL;
  99.     }        
  100. #endif
  101.     return TRUE;
  102. }
  103.  
  104.  
  105. BOOL ShutdownDD() {
  106.     if (lpdd != NULL) {
  107.         if (lpddps != NULL) {
  108.             lpddps->Release();
  109.             lpddps = NULL;
  110.         }
  111.         lpdd->RestoreDisplayMode();
  112.         lpdd->Release();
  113.         lpdd = NULL;
  114.     }
  115.     return TRUE;
  116. }
  117.  
  118.  
  119. BOOL CreateSurface(LPDDS &lpdds, DWORD dwWidth, DWORD dwHeight) {
  120.     DDSD ddsd;
  121.     HRESULT    ddrval;
  122.  
  123.     ZeroMemory(&ddsd, sizeof(ddsd));
  124.     ddsd.dwSize = sizeof(ddsd);
  125.     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  126.  
  127.     ddsd.dwWidth = dwWidth;
  128.     ddsd.dwHeight = dwHeight;
  129.  
  130.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  131.     
  132.     ddrval = lpdd->CreateSurface(&ddsd,&lpdds,NULL);
  133.     return (ddrval == DD_OK);
  134. }
  135.  
  136.  
  137. BOOL CopyBitmap(LPDDS lpdds, HBITMAP hbm, int x, int y, int dx, int dy) {
  138.     HDC         hdcImage;
  139.     HDC         hdc;
  140.     BITMAP      bm;
  141.     DDSD        ddsd;
  142.     HRESULT     ddrval;
  143.  
  144.     if (hbm == NULL || lpdds == NULL)
  145.         return FALSE;
  146.  
  147.     lpdds->Restore();
  148.  
  149.     hdcImage = CreateCompatibleDC(NULL);
  150.     if (!hdcImage)
  151.         return FALSE;
  152.     
  153.     SelectObject(hdcImage, hbm);
  154.  
  155.     GetObject(hbm, sizeof(bm), &bm);
  156.     dx = dx == 0 ? bm.bmWidth  : dx;
  157.     dy = dy == 0 ? bm.bmHeight : dy;
  158.  
  159.     ddsd.dwSize = sizeof(ddsd);
  160.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  161.     ddrval = lpdds->GetSurfaceDesc(&ddsd);
  162.     if (ddrval != DD_OK) 
  163.         return FALSE;
  164.  
  165.     ddrval = lpdds->GetDC(&hdc);
  166.     if (ddrval == DD_OK) {    
  167.         StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
  168.         lpdds->ReleaseDC(hdc);
  169.     }
  170.     DeleteDC(hdcImage);
  171.  
  172.     return (ddrval==DD_OK);
  173. }
  174.  
  175.  
  176. BOOL CreateSurface(LPDDS &lpdds, const char * filename, DWORD dx, DWORD dy) {
  177.     HRESULT ddrval;
  178.     HBITMAP hbm;
  179.     BITMAP bm;
  180.     DDSD ddsd;
  181.  
  182.     hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), filename, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
  183.  
  184.     if (hbm == NULL)
  185.     hbm = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  186.  
  187.     if (hbm == NULL)
  188.         return FALSE;
  189.     
  190.     GetObject(hbm, sizeof(bm), &bm);
  191.  
  192.     ZeroMemory(&ddsd, sizeof(ddsd));
  193.     ddsd.dwSize = sizeof(ddsd);
  194.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  195.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  196.     ddsd.dwWidth = bm.bmWidth;
  197.     ddsd.dwHeight = bm.bmHeight;
  198.  
  199.     ddrval = lpdd->CreateSurface(&ddsd, &lpdds, NULL);
  200.     if (ddrval != DD_OK)
  201.         return FALSE;
  202.         
  203.     CopyBitmap(lpdds, hbm, 0, 0, 0, 0);
  204.     DeleteObject(hbm);
  205.  
  206.     return TRUE;
  207. }
  208.  
  209.  
  210. BOOL CreateClipper(LPDIRECTDRAWCLIPPER &Clipper, LPRECT ClipList, DWORD nListSize) {
  211.     HRESULT ddrval;
  212.     LPRGNDATA regiondata;
  213.  
  214.     ddrval = lpdd->CreateClipper(0,&Clipper,NULL);
  215.     if (ddrval != DD_OK)
  216.         return FALSE;
  217.  
  218.     regiondata = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) +
  219.                   nListSize*sizeof(RECT));
  220.  
  221.     memcpy(regiondata->Buffer, ClipList, sizeof(RECT)*nListSize);
  222.     regiondata->rdh.dwSize = sizeof(RGNDATAHEADER);
  223.     regiondata->rdh.iType = RDH_RECTANGLES;
  224.     regiondata->rdh.nCount = nListSize;
  225.     regiondata->rdh.nRgnSize = nListSize*sizeof(RECT);
  226.  
  227.     regiondata->rdh.rcBound.left = 64000;
  228.     regiondata->rdh.rcBound.top = 64000;
  229.     regiondata->rdh.rcBound.right = -64000;
  230.     regiondata->rdh.rcBound.bottom = -64000;
  231.  
  232.     for (int i=0; i<(int)nListSize; i++) {
  233.         if (ClipList[i].left < regiondata->rdh.rcBound.left) 
  234.             regiondata->rdh.rcBound.left = ClipList[i].left;
  235.         if (ClipList[i].top < regiondata->rdh.rcBound.top) 
  236.             regiondata->rdh.rcBound.top = ClipList[i].top;
  237.         if (ClipList[i].right > regiondata->rdh.rcBound.right) 
  238.             regiondata->rdh.rcBound.right = ClipList[i].right;
  239.         if (ClipList[i].bottom > regiondata->rdh.rcBound.bottom) 
  240.             regiondata->rdh.rcBound.bottom = ClipList[i].bottom;
  241.     }
  242.  
  243.     if (Clipper->SetClipList(regiondata,0) != DD_OK) {
  244.         free(regiondata);
  245.         return FALSE;
  246.     }
  247.  
  248.     free(regiondata);
  249.     return TRUE;
  250. }
  251.  
  252.  
  253. BOOL CreateClipper(LPDIRECTDRAWCLIPPER &Clipper, HWND hWnd) {
  254.     HRESULT ddrval;
  255.  
  256.     ddrval = lpdd->CreateClipper(0,&Clipper,NULL);
  257.     if (ddrval != DD_OK)
  258.         return FALSE;
  259.  
  260.     ddrval = Clipper->SetHWnd(0,hWnd);
  261.     if (ddrval != DD_OK) 
  262.         return FALSE;
  263.  
  264.     return TRUE;
  265. }
  266.  
  267.  
  268. BOOL CreatePalette(LPDIRECTDRAWPALETTE &Palette, PALETTEENTRY * Entries) {
  269.     HRESULT ddrval;
  270.     ddrval = lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE |
  271.                                  DDPCAPS_ALLOW256 , Entries, &Palette, NULL);
  272.     
  273.     return (ddrval == DD_OK);
  274. }
  275.  
  276.  
  277. BOOL VerifyDD() {
  278.     HRESULT ddrval;
  279.     ddrval = lpddps->IsLost();
  280.     if (ddrval != DD_OK) {
  281.         if (ddrval == DDERR_SURFACELOST) {
  282.             ddrval = lpdd->RestoreAllSurfaces();
  283.             if (ddrval != DD_OK && ddrval != DDERR_WRONGMODE) 
  284.                 return FALSE;
  285.  
  286.             return (RestoreAll(ddrval == DDERR_WRONGMODE));            
  287.         } 
  288.         else {
  289.             return FALSE;
  290.         }
  291.     }
  292.     return TRUE;
  293. }
  294.  
  295.  
  296. BOOL Blit(LPDDS Source, LPDDS Dest, DWORD x, DWORD y) {
  297.     HRESULT ddrval;
  298.     DDSD ddsd;
  299.  
  300.     if (!VerifyDD()) 
  301.         return FALSE;
  302.  
  303.     ZeroMemory(&ddsd, sizeof(ddsd));
  304.     ddsd.dwSize = sizeof(ddsd);
  305.     ddrval = Source->GetSurfaceDesc(&ddsd);
  306.     if (ddrval != DD_OK)
  307.         return FALSE;
  308.  
  309.     RECT ImageSize = { 0, 0, ddsd.dwWidth-1, ddsd.dwHeight-1 };
  310.     ddrval = Dest->BltFast(x,y,Source,&ImageSize, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
  311.     
  312.     return (ddrval == DD_OK);
  313. }
  314.  
  315.  
  316. BOOL Blit(LPDDS Source, LPRECT SrcRect, LPDDS Dest, LPRECT DstRect, DWORD ColorKey) {
  317.     HRESULT ddrval;
  318.     DDCOLORKEY ck;
  319.  
  320.     ck.dwColorSpaceLowValue = ColorKey;
  321.     ck.dwColorSpaceHighValue = ColorKey;
  322.  
  323.     VerifyDD();
  324.  
  325.     ddrval = Source->SetColorKey(DDCKEY_SRCBLT,&ck);
  326.     if (ddrval != DD_OK) 
  327.         return FALSE;
  328.  
  329.     ddrval = Dest->Blt(DstRect,Source,SrcRect,DDBLT_KEYSRC | DDBLT_WAIT, NULL);
  330.  
  331.     return (ddrval == DD_OK);
  332. }
  333.  
  334.  
  335. BOOL Fill(LPRECT Region, DWORD Color, LPDDS lpdds) {
  336.     DDBLTFX ddbltfx;
  337.     DDSD ddsd;
  338.     HRESULT ddrval;
  339.     RECT Contents;
  340.  
  341.     if (Region==NULL) {
  342.         ZeroMemory(&ddsd,sizeof(ddsd));
  343.         ddsd.dwSize = sizeof(ddsd);
  344.  
  345.         ddrval = lpdds->GetSurfaceDesc(&ddsd);
  346.         if (ddrval != DD_OK) 
  347.             return FALSE;
  348.         Contents.left = 0;
  349.         Contents.top = 0;
  350.         Contents.right = ddsd.dwWidth;
  351.         Contents.bottom = ddsd.dwHeight;
  352.     }
  353.     else {
  354.         Contents = *Region;
  355.     }
  356.     
  357.     ZeroMemory(&ddbltfx, sizeof(ddbltfx));
  358.     ddbltfx.dwSize = sizeof(ddbltfx);
  359.     ddbltfx.dwFillColor = Color;
  360.  
  361.     VerifyDD();
  362.  
  363.     ddrval = lpdds->Blt(&Contents, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx);    
  364.     return (ddrval == DD_OK);
  365. }
  366.  
  367.  
  368. BOOL Fill(DWORD x1, DWORD y1, DWORD x2, DWORD y2, DWORD Color, LPDDS lpdds) {
  369.     RECT Region = { x1, y1, x2, y2 };
  370.     return Fill(&Region, Color, lpdds);
  371. }
  372.  
  373.  
  374. BOOL Flip() {
  375.     HRESULT ddrval;
  376.     
  377.     VerifyDD();
  378.  
  379.     ddrval = lpddps->Flip(NULL,DDFLIP_WAIT);
  380.     return (ddrval == DD_OK) ;
  381. }
  382.  
  383.  
  384. BOOL LoadSurface(const char * filename, DWORD dx, DWORD dy, LPDDS lpdds) {
  385.     HBITMAP hbm;
  386.     BOOL rval;
  387.  
  388.     hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), filename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  389.  
  390.     if (hbm == NULL)
  391.         hbm = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  392.  
  393.     if (hbm == NULL)
  394.         return FALSE;
  395.     
  396.     rval = CopyBitmap(lpdds, hbm, dx, dy, 0, 0);
  397.     
  398.     DeleteObject(hbm);
  399.     return rval;
  400. }
  401.  
  402.  
  403. BOOL Lock(LPDDS lpdds, DDSD &ddsd) {
  404.     HRESULT ddrval;
  405.  
  406.     ZeroMemory(&ddsd,sizeof(ddsd));
  407.     ddsd.dwSize = sizeof(ddsd);
  408.  
  409.     VerifyDD();
  410.  
  411.     ddrval = lpdds->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  412.     return (ddrval == DD_OK);
  413. }
  414.  
  415.  
  416. BOOL Unlock(LPDDS lpdds) {
  417.     HRESULT ddrval;
  418.     ddrval = lpdds->Unlock(NULL);
  419.     return (ddrval == DD_OK);
  420. }
  421.  
  422.  
  423. DWORD ColorMatch(COLORREF rgb, LPDDS lpdds) {
  424.     COLORREF rgbT;
  425.     HDC hdc;
  426.     DWORD dw = CLR_INVALID;
  427.     DDSD ddsd;
  428.     HRESULT ddrval;
  429.  
  430.     if (rgb != CLR_INVALID && lpdds->GetDC(&hdc) == DD_OK) {
  431.         rgbT = GetPixel(hdc, 0, 0);
  432.         SetPixel(hdc, 0, 0, rgb);
  433.         lpdds->ReleaseDC(hdc);
  434.     }
  435.  
  436.     ddsd.dwSize = sizeof(ddsd);
  437.     ddrval = lpdds->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
  438.  
  439.     if (ddrval == DD_OK) {
  440.         dw  = *(DWORD *)ddsd.lpSurface;
  441.         dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;
  442.         lpdds->Unlock(NULL);
  443.     }
  444.  
  445.     if (rgb != CLR_INVALID && lpdds->GetDC(&hdc) == DD_OK) {
  446.         SetPixel(hdc, 0, 0, rgbT);
  447.         lpdds->ReleaseDC(hdc);
  448.     }
  449.  
  450.     return dw;
  451. }
  452.  
  453.  
  454. BOOL GetSurfaceSize(LPDDS lpdds, LPRECT Size) {
  455.     Size->left = 0;
  456.     Size->top = 0;
  457.  
  458.     DDSD ddsd;
  459.     HRESULT ddrval;
  460.  
  461.     ZeroMemory(&ddsd,sizeof(ddsd));
  462.     ddsd.dwSize = sizeof(ddsd);
  463.     ddrval = lpdds->GetSurfaceDesc(&ddsd);
  464.     if (ddrval != DD_OK) 
  465.         return FALSE;
  466.  
  467.     Size->right = ddsd.dwWidth - 1;
  468.     Size->bottom = ddsd.dwHeight - 1;
  469.     return TRUE;
  470. }
  471.  
  472.